﻿using Devil;
using OfficeOpenXml;
using System.Collections.Generic;
using System.Data;
using System.IO;

namespace TableCore
{
    public partial class GTFile
    {
        public class Content
        {
            GTFile mWorkFile;
            string mExcelFile;
            DataSet mData;
            ClassModel mCmodel;
            int mIndex;
            public int TableIndex { get { return mIndex; } }
            public DataSet Data { get { return mData; } }
            public ClassModel Cmodel { get { return mCmodel; } }
            public string File { get { return mExcelFile; } }
            public GTFile WorkFile { get { return mWorkFile; } }

            public Content(GTFile workFile, string file, DataSet data, ClassModel cmod, int index)
            {
                mWorkFile = workFile;
                mExcelFile = file;
                mData = data;
                mCmodel = cmod;
                mIndex = index;
            }
        }

        internal class GenDataVariant
        {
            int[] atCols;
            string variant;

            public MinHeap<GenData> genDatas;

            public string Variant { get { return variant; } }

            public GenDataVariant(ClassModel cmod, string variant, int initCount)
            {
                this.variant = variant;
                atCols = new int[cmod.PropertyCount];
                for (int i = 0; i < atCols.Length; i++)
                {
                    atCols[i] = -1;
                }
                genDatas = new MinHeap<GenData>(initCount, (a, b) => a.id < b.id ? -1 : (a.id > b.id ? 1 : 0));
            }

            public int GetPropertyCols(int propertyIndex)
            {
                return atCols[propertyIndex];
            }

            public static void GetPropertiesIndex(ClassModel cmod, DataTable table, int startRow, int startCol, IList<GenDataVariant> map)
            {
                var cols = table.Columns.Count;
                for (int col = startCol; col < cols; col++)
                {
                    var cell = Utils.GetCell(table, startRow, col);
                    if (string.IsNullOrEmpty(cell))
                        break;
                    if (!ClassModel.PROPERTY_PATTERN.IsMatch(cell))
                        continue;
                    var n = cell.LastIndexOf('.');
                    string variantName = null;
                    if (n > 0)
                    {
                        variantName = cell.Substring(n + 1);
                        cell = cell.Substring(0, n);
                    }
                    var pindex = cmod.IndexOfProperty(cell);
                    if (pindex == -1)
                        continue;
                    if (string.IsNullOrEmpty(variantName))
                    {
                        for (int k = 0; k < map.Count; k++)
                        {
                            map[k].atCols[pindex] = col;
                        }
                    }
                    else
                    {
                        for (int k = 0; k < map.Count; k++)
                        {
                            if (StringUtil.EqualIgnoreCase(variantName, map[k].variant))
                            {
                                map[k].atCols[pindex] = col;
                            }
                        }
                    }
                }
            }
        }
    
    
        public static void SaveTablesAsExcel(DataSet set, string filePath)
        {
            var folder = Utils.GetFolderName(filePath);
            if (!Directory.Exists(folder))
                Directory.CreateDirectory(folder);
            var excel = new ExcelPackage(new FileInfo(filePath));
            for (int tabIndex = 0; tabIndex < set.Tables.Count; tabIndex++)
            //foreach (DataTable table in set.Tables)
            {
                var tab = set.Tables[tabIndex];
                ExcelWorksheet excelSheet = null;
                foreach (var book in excel.Workbook.Worksheets)
                {
                    if (book.Name == tab.TableName)
                    {
                        excelSheet = book;
                        break;
                    }
                }
                var rows = tab.Rows;
                var cols = tab.Columns;
                double[] colsize = new double[ParallelUtils.Max(4, cols.Count)];
                if (excelSheet == null)
                {
                    excelSheet = excel.Workbook.Worksheets.Add(tab.TableName);
                    colsize[0] = 25;
                    colsize[1] = 20;
                    colsize[2] = 20;
                    for (int i = 3; i < colsize.Length; i++)
                    {
                        colsize[i] = 30;
                    }
                }
                else
                {
                    for (int i = 0; i < colsize.Length; i++)
                    {
                        colsize[i] = ParallelUtils.Max(20, (int)excelSheet.Column(i + 1).Width);
                        if (colsize[i] > 80)
                            colsize[i] = 80;
                    }
                }
                excelSheet.Cells.Clear();
                for (int r = 0; r < rows.Count; r++)
                {
                    for (int c = 0; c < cols.Count; c++)
                    {
                        excelSheet.Cells[r + 1, c + 1].Value = rows[r][c];
                    }
                }

                for (int i = 0; i < colsize.Length; i++)
                {
                    excelSheet.Column(i + 1).Width = colsize[i];
                }
            }
            excel.Save();
            excel.Dispose();
        }

    }
}
